
<script>
import { createNamespacedHelpers, mapGetters } from 'vuex';
const { mapMutations } = createNamespacedHelpers('view');
const { mapMutations: canvasMapMutations } = createNamespacedHelpers('canvas');
import draggable from 'vuedraggable';
const moduleFiles = require.context('../../../public/config/', true, /\.json$/);
const moduleData = moduleFiles.keys().map((obj) => {
  return moduleFiles(obj);
}, {});
const data = require('./data');
const mock = require('mockjs');
const textArr = [
  '输入型组件',
  '选择型组件',
  '功能型组件',
  '布局型组件',
  '图表组件',
  '本地自定义html组件',
  '保存的画布'
];
const textSvg = ['input', 'select', 'table', 'row', 'pie', 'html', 'canvas'];
export default {
  name: 'TagsContainer',
  components: { draggable },
  props: {},
  data() {
    return {
      drag: true,
      element: null,
      el: null,
      activeIndex: 0,
      ...data
    };
  },
  computed: {
    ...mapGetters([
      'componentsList',
      'localList',
      'viewType',
      'theme',
      'canvasList'
    ])
  },
  mounted() {},
  methods: {
    ...mapMutations({
      setComponentsList: 'SET_COMPONENTS_LIST',
      setComponent: 'SET_COMPONENT',
      changeComponent: 'CHANGE_COMPONENT',
      removeHtmlComponent: 'REMOVE_HTMLCOMPONENT',
      updateComponentList: 'UPDATE_COMPONENTS_LIST'
    }),
    ...canvasMapMutations({
      setCanvas: 'SET_CANVAS',
      removeCanvas: 'REMOVE_CANVAS',
      updateCanvas: 'UPDATE_CANVAS'
    }),
    getTableOption(el) {
      const t = mock.mock({
        'tableColumn|5-15': [
          {
            'id|+1': 1,
            ...this.columnParams,
            label: '@ctitle(3,5)',
            prop: '@word(3,6)'
          }
        ]
      });
      el['__options__'].tableColumn = t.tableColumn;
      let obj = {};
      t.tableColumn.map((item) => {
        obj[item.prop] = '@ctitle(3,5)';
      });

      const d = mock.mock({
        'tableData|3-10': [obj]
      });
      el['__options__'].total = d.tableData.length;
      el['__options__'].tableData = d.tableData;
      return el;
    },
    getID(list, index) {
      let i = index;
      list.map((item) => {
        i++;
        if (item.__config__.children && item.__config__.children.length > 0) {
          this.getID(item.__config__.children, i);
        }
      });
      return i;
    },
    clone(e, type) {
      let el = moduleData.find((item) => item['__componentName__'] === e.type);
      try {
        el = JSON.parse(JSON.stringify(el));
        el = { ...el, ...e };
        let newId = '';
        if (this.viewType === 'drag') {
          newId = this.getID(this.componentsList, 0);
        } else {
          newId = new Date().getTime();
        }

        el['__field__'] = 'field' + newId;
        el['__options__'].className = el['__componentName__'] + newId;
        el.id = newId;
        if (e.type === 'tableComponent') {
          el = this.getTableOption(el);
        } else if (e.echarts) {
          el['__options__'].id = 'id' + newId;
        }
        if (type === 'check') {
          this.setComponentsList(el);
          this.changeComponent(el);
        }
        this.el = el;
        // this.changeComponent(el);
        return el;
      } catch (error) {
        this.$message.error('配置文件或vue文件不存在');
      }
      // return moduleData
      // this.element = e;
    },

    onEnd(e) {
      if (this.viewType === 'drag') {
        const left = e.originalEvent.layerX;
        const top = e.originalEvent.layerY;
        this.el.__commonOptions__.left = left;
        this.el.__commonOptions__.top = top;
        this.clone(this.el, 'check');
      }
      if (e.from !== e.to) {
        this.changeComponent(this.el);
      }
    },
    getImgUrl(icon) {
      return icon
        ? require(`../../assets/svg/${icon}.svg`)
        : require(`../../assets/svg/canvas.svg`);
    },
    removeTag(tag, type) {
      if (type === 'html') {
        this.removeHtmlComponent(tag);
      } else {
        this.removeCanvas(tag);
      }
    },
    setCanvasFn(canvasList, obj) {
      this.$prompt('请输入画布名称', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputValidator: (value) => {
          const a = canvasList.find((item) => item.label === value);
          if (!value) {
            return '输入不能为空';
          } else if (a) {
            return '画布名称重复';
          }
        }
      })
        .then(({ value }) => {
          this.setCanvas({
            id: 'id' + (canvasList.length + 1),
            label: value,
            componentsList: JSON.parse(JSON.stringify(this.componentsList))
          });
          this.updateComponentList(obj.componentsList);
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '取消保存'
          });
        });
    },
    changeCanvas(e) {
      const canvasList = JSON.parse(localStorage.getItem('canvasList'));
      const obj = canvasList.find((item) => item.id === e.id);

      if (this.componentsList.length) {
        this.$confirm('是否保存当前画布?', '提示', {
          confirmButtonText: '保存当前画布',
          cancelButtonText: '直接切换',
          type: 'warning',
          distinguishCancelAndClose: true,
          callback: (res) => {
            if (res === 'cancel') {
              this.updateCanvas(obj);
              this.updateComponentList(obj.componentsList);
            } else if (res === 'confirm') {
              this.setCanvasFn(canvasList, obj);
            }
          }
        });
      } else {
        this.updateComponentList(obj.componentsList);
      }
    },
    getToolTip(d, index) {
      return (
        <el-tooltip
          class="item"
          effect="dark"
          content={textArr[index]}
          placement="right"
        >
          <div
            class={[
              'tab',
              {
                active: this.activeIndex === index
              },
              {
                nomarl: this.theme === 'normal-theme'
              }
            ]}
            onClick={() => {
              this.activeIndex = index;
            }}
          >
            <i class={['iconfont', 'icon-' + textSvg[index]]}></i>
          </div>
        </el-tooltip>
      );
    },
    getTagBox(item, index) {
      return (
        <div class={['tag-box', { show: this.activeIndex === index }]}>
          <draggable
            v-model={item}
            animation="300"
            class="tags"
            draggable=".tag"
            disabled={index === 6}
            clone={this.clone}
            {...{
              on: {
                end: this.onEnd
              }
            }}
            options={{
              group: { name: 'site', pull: 'clone', put: false },
              sort: false
            }}
          >
            {item.map((d) => {
              if (d.children) {
                return '123';
              } else {
                return this.getTag(d, index);
              }
            })}
          </draggable>
        </div>
      );
    },
    getTag(d, index) {
      const flag = textSvg[index] === 'html' || textSvg[index] === 'canvas';
      const title = `确定删除该${
        textSvg[index] === 'html' ? '组件' : '画布'
      }吗？ `;
      return (
        <div
          class="tag"
          onClick={() =>
            textSvg[index] === 'canvas'
              ? this.changeCanvas(d)
              : this.clone(d, 'check')
          }
        >
          {flag ? (
            <el-popconfirm
              title={title}
              {...{
                on: {
                  confirm: (e) => {
                    this.removeTag(d, textSvg[index]);
                  }
                }
              }}
            >
              <el-button
                slot="reference"
                icon="el-icon-delete"
                type="text"
                class="remove-html-btn"
                style="color:red;"
                onClick={(e) => {
                  e.stopPropagation();
                }}
              ></el-button>
            </el-popconfirm>
          ) : (
            ''
          )}

          <img src={this.getImgUrl(d.icon)} />
          {d.label}
        </div>
      );
    }
  },
  render() {
    const {
      inputList,
      selectList,
      specialList,
      layoutList,
      echartsList,
      localList,
      canvasList
    } = this;
    const obj = {
      inputList,
      selectList,
      specialList,
      layoutList,
      echartsList,
      localList,
      canvasList
    };
    return (
      <el-scrollbar>
        <div class={['tags-container', { dark: this.theme === 'dark-theme' }]}>
          <div class="tabs">
            {textArr.map((d, index) => {
              return this.getToolTip(d, index);
            })}
          </div>
          <div class="block">
            {Object.values(obj).map((item, index) => {
              return this.getTagBox(item, index);
            })}
          </div>
        </div>
      </el-scrollbar>
    );
  }
};
</script>

<style lang="scss" scoped>
.tags-container {
  padding-left: 15px;
  height: calc(100vh - 51rem);
  // background-color: #fff;
  display: flex;
  .tabs {
    height: 100%;
    width: 60rem;
    margin-right: 10rem;
    .tab {
      width: 50rem;
      height: 50rem;
      cursor: pointer;
      transition: background-color 0.3s;
      border: 1px solid #ddd;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 30rem;
      color: rgba(255, 255, 255, 0.7);
      &.nomarl {
        color: #333;
      }
      &.active {
        background-color: rgb(15, 13, 175);
        color: #fff;
        transition: background-color 0.3s;
      }

      // background-color: aqua;
    }
  }
  &.dark {
    background-color: transparent;
    .title {
      color: #fff !important;
    }
    .tag {
      background-color: transparent !important;
      border: 1px solid #0981e4 !important;
      color: #fff !important;
      img {
        filter: invert(1);
      }
    }
  }
  ::v-deep {
    .el-scrollbar {
      height: 100%;
    }
    .el-scrollbar__wrap {
      overflow-x: hidden;
    }
  }
  .block {
    flex: 1;
    .title {
      margin-bottom: 15px;
    }
    .tag-box {
      display: none;
      &.show {
        display: block;
      }
    }
    .tags {
      display: flex;
      flex-wrap: wrap;
      width: 100%;
      margin-bottom: 10px;
      margin-right: 10px;

      .tag {
        width: 30%;
        padding: 8px 10px;
        background: #f6f7ff;
        font-size: 12px;
        cursor: move;
        border: 1px dashed #f6f7ff;
        border-radius: 3px;
        margin-bottom: 10px;
        margin-right: 10px;
        text-align: center;
        display: flex;
        align-items: center;
        flex-direction: column;
        position: relative;
        .remove-html-btn {
          position: absolute;
          right: 0;
          top: 0;
        }
        img {
          width: 40px;
          margin-bottom: 10px;
        }
        &:hover {
          border: 1px dashed #ddd;
        }
      }
    }
  }
}
</style>
